package dormouse.fx.event;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javafx.event.Event;
import javafx.event.EventHandler;
import dormouse.vfs.event.IEventMixin;

/**
 * This mixin provides event support.
 */
public class EventMixin<L extends EventHandler, E extends Event> implements IEventMixin<L, E> {
	
	private List<L> listenerList = new ArrayList<L>();
	
	/** The executor. */
	private ThreadPoolExecutor exec = new ThreadPoolExecutor(5, 10, 5,
			TimeUnit.SECONDS, new ArrayBlockingQueue(50));

	

	@Override
	public void addListener(L listener) {
		listenerList.add(listener);
	}

	@Override
	public void removeListener(L listener) {
		listenerList.remove(listener);
	}

	@Override
	public void notify(E event) {
		for(L listener : listenerList){
			exec.submit(new Notifier(event, listener));
		}
		
	}
	
	/**
	 * This task is responsible for notifying listeners of file selection
	 * events.
	 */
	class Notifier implements Callable {

		/** The event to be broadcast. */
		private E event;
		
		/** The listener to be notified. */
		private L listener;

		/**
		 * Constructor.
		 * 
		 * @param event the event to be broadcast.
		 * @param listener the listener to be notified.
		 */
		public Notifier(final E event,
				final L listener) {
			this.event = event;
			this.listener = listener;
		}

		@Override
		public Object call() throws Exception {
			listener.handle(event);
			return null;
		}

	}

}
